﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Windows.Media;
using System.Windows;
using System.Windows.Controls;
using XWord.Fundamental.Domain.Services;
using System.Threading;
using System.Windows.Documents;
using Microsoft.Practices.ServiceLocation;
using System.Windows.Input;
using System.Windows.Controls.Primitives;
using XWord.GUI.Presenters.Interface;
using XWord.Common;
using XWord.Fundamental.Domain;

namespace XWord.GUI.Presenters.Adorns
{
    public interface IAdorner
    {
        UIElement AdornedElement { get; }
    }

    public class WordMarkAdorner : Adorner, IAdorner
    {
        private ItemsControl _itemsControl;

        public WordMarkAdorner(UIElement adornedElement)
            : base(adornedElement)
        {
            tip = new ToolTip();
            tip.Placement = PlacementMode.Mouse;
            tip.StaysOpen = true;
            _itemsControl = adornedElement as ItemsControl;
            _itemsControl.AddHandler(ScrollViewer.ScrollChangedEvent, new ScrollChangedEventHandler(ScrollOwner_ScrollChanged));
            WordBehavior.WordEventHandler += new WordEventHandler(WordBehavior_WordEventHandler);
        }

        void WordBehavior_WordEventHandler(object sender, WordEventArgs args)
        {
            switch (args.Action)
            {
                case WordAction.Add:
                    InitWordState(args.Word.Name);
                    this.InvalidateVisual();
                    break;
                case WordAction.Remove:

                    break;
            }
        }

        void ScrollOwner_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            // this.InvalidateMeasure();
            verticalOffset = e.VerticalOffset;
            if (ExamCriterion == null) return;
            this.InvalidateVisual();
        }

        private double verticalOffset;

        public string WordName { get; set; }

        public Dictionary<string,Word> _examCriterion;
        public Dictionary<string, Word> ExamCriterion
        {
            get
            {
                return ServiceLocator.Current.GetInstance<IWordExplorerPresenter>().EntityList;
            }
        }

        public IWordBehavior WordBehavior
        {
            get
            {
                return ServiceLocator.Current.GetInstance<IWordBehavior>();
            }
        }

        private SolidColorBrush GetFamiliarBrush(bool isFamiliar)
        {
            if (isFamiliar)
            {
                return Brushes.Green;
            }
            else
            {
                return Brushes.Red;
            }
        }

        private SolidColorBrush GetCET4Brush(bool isCET4)
        {
            if (isCET4)
            {
                return Brushes.LimeGreen;
            }
            else
            {
                return Brushes.DarkGray;
            }
        }

        private SolidColorBrush GetCET6Brush(bool isCET6)
        {
            if (isCET6)
            {
                return Brushes.ForestGreen;
            }
            else
            {
                return Brushes.Gainsboro;
            }
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            var pos = e.GetPosition(this);


            var blockIndex = GetBlockIndex(pos);
            switch (blockIndex)
            {
                case 0:
                    tip.Content = "已记住单词";
                    break;
                case 1:
                    tip.Content = "四级单词";
                    break;
                case 2:
                    tip.Content = "小建记住的单词";
                    break;
            }
            if (blockIndex >= 0 && blockIndex <= 2)
            {
                if (!tip.IsOpen)
                    tip.IsOpen = true;
            }
            else
            {
                tip.IsOpen = false;
            }
            base.OnMouseMove(e);
        }

        protected override void OnMouseLeave(MouseEventArgs e)
        {
            tip.IsOpen = false;
            base.OnMouseLeave(e);
        }

        private ToolTip tip;

        private int GetBlockIndex(Point pos)
        {
            for (int i = 0, j = 9; i < 3; i++, j -= 3)
            {
                if ((pos.X >= (InternalWidth - j * renderRadius)) && pos.X <= (InternalWidth - (j - 2) * renderRadius))
                {
                    return i;
                }
            }
            return 0;
        }

        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            var pos = e.GetPosition(this);

            var currentIndex = GetCurrentItem(pos);
            var word = _itemsControl.Items[currentIndex].ToString();
            var ht = ExamCriterion[word] as Word;
            var blockIndex = GetBlockIndex(pos);
            switch (blockIndex)
            {
                case 0:
                    ht.IsFamiliar = !ht.IsFamiliar;
                    break;
                case 1:
                    ht.IsCET4 = !ht.IsCET4;
                    break;
                case 2:
                    ht.IsCET6 = !ht.IsCET6;
                    break;
            }
            if (blockIndex >= 0 && blockIndex <= 2)
            {
               // wordService.SaveSingelEntity(BinaryFiles.ExamCriterion, word, ht);
                this.InvalidateVisual();
            }
            base.OnMouseLeftButtonDown(e);
        }

        private void ReverseHashBoolean(Hashtable ht, string key)
        {
            ht[key] = !Convert.ToBoolean(ht[key]);
        }

        private int GetCurrentItem(Point point)
        {
            var index = Convert.ToInt32(verticalOffset);
            var item0 = _itemsControl.ItemContainerGenerator.ContainerFromIndex(index) as FrameworkElement;
            var cursorIndex = Math.Floor(point.Y / item0.DesiredSize.Height);
            return Convert.ToInt32(index + cursorIndex);
        }

        private double renderRadius = 7.0;
        private double InternalWidth;
        private double EllipseWidth
        {
            get
            {
                return renderRadius * 2;
            }
        }

        private SolidColorBrush familiarBrush = Brushes.Green;

        private void InitWordState(string word)
        {
            //var mark = new Hashtable();
            //mark["IsFamiliar"] = false;
            //mark["IsCET4"] = false;
            //mark["IsCET6"] = false;
            //ExamCriterion[word] = mark;
            //wordService.SaveSingelEntity(BinaryFiles.ExamCriterion, word, mark);
        }

        private void RemoveWordState(string word)
        {
            if (ExamCriterion.ContainsKey(word))
            {
                ExamCriterion.Remove(word);
                wordService.SaveSingelEntity(BinaryFiles.ExamCriterion, word, null);
            }
        }

        private IWordService wordService
        {
            get { return RemotingServiceFactory.GetWordService(); }
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            if (_itemsControl.Items.Count == 0 || ExamCriterion == null) return;

            Pen renderPen = new Pen(Brushes.Black, 1);
            renderPen.Freeze();


            var index = Convert.ToInt32(verticalOffset);
            var item0 = _itemsControl.ItemContainerGenerator.ContainerFromIndex(index) as FrameworkElement;
            var rect = new Rect(item0.RenderSize);

            var count = Math.Ceiling(_itemsControl.ActualHeight / rect.Height);
            InternalWidth = rect.Width;
            for (int i = 0; i < count; i++)
            {
                if (index >= _itemsControl.Items.Count) return;
                var word = _itemsControl.Items[index++].ToString();
                var ht = ExamCriterion[word] as Word;
                if (ht == null)
                {
                    InitWordState(word);
                }
                if (ht != null)
                {
                    var height = rect.Height * (i + 0.6);
                    drawingContext.DrawEllipse(GetFamiliarBrush(ht.IsFamiliar), renderPen,
                           new Point(rect.Width - renderRadius * 8, height),
                           renderRadius, renderRadius);

                    drawingContext.DrawEllipse(GetFamiliarBrush(ht.IsCET4), renderPen,
                           new Point(rect.Width - renderRadius * 5, height),
                           renderRadius, renderRadius);

                    drawingContext.DrawEllipse(GetFamiliarBrush(ht.IsCET6), renderPen,
                           new Point(rect.Width - renderRadius * 2, height),
                           renderRadius, renderRadius);
                }
            }
            Console.WriteLine(DateTime.Now);
        }
    }
}
